/***********************************************************************************
 * 文件名： cap_sensor.c
 * 版本： 3
 * 说明：
 * 		纯软件实现的电容传感器组件，可以看做是一个转换的模拟量是电容值的ADC，可以利用普通IO口
 * 	测量电容。转换的结果只是一个采样值，这个值对应的电容值需要与基准电容的采样值进行比较才能准
 * 	确算出电容值，这个需要使用者自行处理。
 * 		可用于电容触摸键的检测，这种场景无需计算准确的电容值，将采样值与一个固定值进行比较即可
 * 	判断按键是否被触摸。
 * 		典型的应用电路见说明文档。采样时处于死等状态，属于耗时操作。
 *      在文件 cap_sensor_config.h 进行正确的配置。
 * 修改记录：
 * 	2021/08/19: 初版。 刘言。
 *  2022/01/17：开关中断API可配置，更改中断开关位置便于示波器观察稳定的充电时间。
 *  2022/05/18: 去掉CPU过采样实现方案。占用优化，新增 _CAPSS_USE_ASYNC_API 配置项。
 ***********************************************************************************/
#include "cap_sensor.h"
#include "..\..\polsys.h"

// #define CAPSS_DEBUG      // 开启调试，采集值将会定义为全局变量，便于查看和获取。

#if ((defined CAPSS_DEBUG) || (defined _CAPSS_USE_ASYNC_API))
    capss_time_t mVihTimes[_CAPSS_CH_NUM], mVilTimes[_CAPSS_CH_NUM];
    capss_value_t mNowValue[_CAPSS_CH_NUM];
    #if _CAPSS_CH_NUM == 1
        #define mNowCH  0
    #endif
#endif

FORCE_IN_LINE void CapSS_Init()
{
    _CapSS_CaptureInit();
    _CapSS_CH0Init();
#if (_CAPSS_CH_NUM > 1)
    _CapSS_CH1Init();
#endif
#if (_CAPSS_CH_NUM > 2)
    _CapSS_CH2Init();
#endif
#if (_CAPSS_CH_NUM > 3)
    _CapSS_CH3Init();
#endif
}

#ifdef _CAPSS_USE_ASYNC_API

static void CapSS_Sampling();

FORCE_IN_LINE capss_value_t CapSS_GetValue(u8 mNowCH)
{
    mNowCH = ch;
    CapSS_Sampling();
    return mNowValue;
}

FORCE_IN_LINE void CapSS_SetCH(u8 ch)
{
    mNowCH = ch;
}

FORCE_IN_LINE u8 CapSS_GetCH()
{
    return mNowCH;
}

FORCE_IN_LINE capss_value_t CapSS_GetLastResult()
{
    return mNowValue;
}

static void CapSS_Sampling()
{
#else
    #if (_CAPSS_CH_NUM > 1)
capss_value_t CapSS_GetValue(u8 mNowCH)
    #else
capss_value_t CapSS_GetValue()
#endif
{
    #ifndef CAPSS_DEBUG
    capss_value_t mNowValue;
    #endif
#endif
    // 关闭中断
    _CapSS_DisableInt();
    //充电
    _CapSS_VloadOutHigh();      // VLOAD输出高电平
#if (_CAPSS_CH_NUM > 1)
    if (mNowCH == 0)
#endif
    {
        _CapSS_CH0OutLow();    // 把电放完（低电平）
        _CapSS_CaptureReady(); // 准备捕获计数
        _CapSS_CH0StartREC();  // 开始捕获计数
        _CapSS_CH0InHZ();      // 开始充电
        while (_CapSS_CH0GetCaptureFlag() == false)
        {
            if (_CapSS_CaptureIsOverflow())
                break;
        }                        //等待捕获高电平
        _CapSS_CH0StopCapture(); //停止捕获计数
#ifdef CAPSS_DEBUG
        if (_CapSS_CaptureIsOverflow())
            mVihTimes[mNowCH] = _CAPSS_MAX_TIME;
        else
            mVihTimes[mNowCH] = _CapSS_CH0GetCaptureValue(); //读取捕获值
#else
        if (_CapSS_CaptureIsOverflow())
            mNowValue = _CAPSS_MAX_TIME * 2;
        else
            mNowValue = _CapSS_CH0GetCaptureValue(); //读取捕获值
#endif
    }
#if (_CAPSS_CH_NUM > 1)
    else if (mNowCH == 1)
    {
        _CapSS_CH1OutLow();    //把电放完（低电平）
        _CapSS_CaptureReady(); //准备捕获计数
        _CapSS_CH1StartREC();  //开始捕获计数
        _CapSS_CH1InHZ();      //开始充电
        while (_CapSS_CH1GetCaptureFlag() == false)
        {
            if (_CapSS_CaptureIsOverflow())
                break;
        }                        //等待捕获高电平
        _CapSS_CH1StopCapture(); //停止捕获计数
#ifdef CAPSS_DEBUG
        if (_CapSS_CaptureIsOverflow())
            mVihTimes[mNowCH] = _CAPSS_MAX_TIME;
        else
            mVihTimes[mNowCH] = _CapSS_CH1GetCaptureValue(); //读取捕获值
#else
        if (_CapSS_CaptureIsOverflow())
            mNowValue = _CAPSS_MAX_TIME * 2;
        else
            mNowValue = _CapSS_CH1GetCaptureValue(); //读取捕获值
#endif
    }
#endif
#if (_CAPSS_CH_NUM > 2)
    else if (mNowCH == 2)
    {
        _CapSS_CH2OutLow();    //把电放完（低电平）
        _CapSS_CaptureReady(); //准备捕获计数
        _CapSS_CH2StartREC();  //开始捕获计数
        _CapSS_CH2InHZ();      //开始充电
        while (_CapSS_CH2GetCaptureFlag() == false)
        {
            if (_CapSS_CaptureIsOverflow())
                break;
        }                        //等待捕获高电平
        _CapSS_CH2StopCapture(); //停止捕获计数
#ifdef CAPSS_DEBUG
        if (_CapSS_CaptureIsOverflow())
            mVihTimes = _CAPSS_MAX_TIME;
        else
            mVihTimes = _CapSS_CH2GetCaptureValue(); //读取捕获值
#else
        if (_CapSS_CaptureIsOverflow())
            mNowValue = _CAPSS_MAX_TIME * 2;
        else
            mNowValue = _CapSS_CH2GetCaptureValue(); //读取捕获值
#endif
    }
#endif
#if (_CAPSS_CH_NUM > 3)
    else if (mNowCH == 3)
    {
        _CapSS_CH3OutLow();    //把电放完（低电平）
        _CapSS_CaptureReady(); //准备捕获计数
        _CapSS_CH3StartREC();  //开始捕获计数
        _CapSS_CH3InHZ();      //开始充电
        while (_CapSS_CH3GetCaptureFlag())
        {
            if (_CapSS_CaptureIsOverflow())
                break;
        }                        //等待捕获高电平
        _CapSS_CH3StopCapture(); //停止捕获计数
#ifdef CAPSS_DEBUG
        if (_CapSS_CaptureIsOverflow())
            mVihTimes = _CAPSS_MAX_TIME;
        else
            mVihTimes = _CapSS_CH3GetCaptureValue(); //读取捕获值
#else
        if (_CapSS_CaptureIsOverflow())
            mNowValue = _CAPSS_MAX_TIME * 2;
        else
            mNowValue = _CapSS_CH3GetCaptureValue(); //读取捕获值
#endif
    }
#endif
    //放电
    _CapSS_VloadOutLow();
#if (_CAPSS_CH_NUM > 1)
    if (mNowCH == 0)
#endif
    {
        _CapSS_CH0OutHigh();   //充满电（高电平）
        _CapSS_CaptureReady(); //准备捕获计数
        _CapSS_CH0StartFEC();  //开始捕获计数
        _CapSS_CH0InHZ();      //开始放电
        while (_CapSS_CH0GetCaptureFlag() == false)
        {
            if (_CapSS_CaptureIsOverflow())
                break;
        }                        //等待捕获低电平
        _CapSS_CH0StopCapture(); //停止捕获计数
#ifdef CAPSS_DEBUG
        if (_CapSS_CaptureIsOverflow())
            mVilTimes[mNowCH] = _CAPSS_MAX_TIME;
        else
            mVilTimes[mNowCH] = _CapSS_CH0GetCaptureValue(); //读取捕获值
#else
        if (_CapSS_CaptureIsOverflow() || mNowValue == _CAPSS_MAX_TIME * 2)
            mNowValue = _CAPSS_MAX_TIME * 2;
        else
            mNowValue += _CapSS_CH0GetCaptureValue(); //读取捕获值
#endif
    }
#if (_CAPSS_CH_NUM > 1)
    else if (mNowCH == 1)
    {
        _CapSS_CH1OutHigh();   //充满电（高电平）
        _CapSS_CaptureReady(); //准备捕获计数
        _CapSS_CH1StartFEC();  //开始捕获计数
        _CapSS_CH1InHZ();      //开始放电
        while (_CapSS_CH1GetCaptureFlag() == false)
        {
            if (_CapSS_CaptureIsOverflow())
                break;
        }                        //等待捕获低电平
        _CapSS_CH1StopCapture(); //停止捕获计数
#ifdef CAPSS_DEBUG
        if (_CapSS_CaptureIsOverflow())
            mVilTimes[mNowCH] = _CAPSS_MAX_TIME;
        else
            mVilTimes[mNowCH] = _CapSS_CH1GetCaptureValue(); //读取捕获值
#else
        if (_CapSS_CaptureIsOverflow() || mNowValue == _CAPSS_MAX_TIME * 2)
            mNowValue = _CAPSS_MAX_TIME * 2;
        else
            mNowValue += _CapSS_CH1GetCaptureValue(); //读取捕获值
#endif
    }
#endif
#if (_CAPSS_CH_NUM > 2)
    else if (mNowCH == 2)
    {
        _CapSS_CH2OutHigh();   //充满电（高电平）
        _CapSS_CaptureReady(); //准备捕获计数
        _CapSS_CH2StartFEC();  //开始捕获计数
        _CapSS_CH2InHZ();      //开始放电
        while (_CapSS_CH2GetCaptureFlag() == false)
        {
            if (_CapSS_CaptureIsOverflow())
                break;
        }                        //等待捕获低电平
        _CapSS_CH2StopCapture(); //停止捕获计数
#ifdef CAPSS_DEBUG
        if (_CapSS_CaptureIsOverflow())
            mVilTimes = _CAPSS_MAX_TIME;
        else
            mVilTimes = _CapSS_CH2GetCaptureValue(); //读取捕获值
#else
        if (_CapSS_CaptureIsOverflow() || mNowValue == _CAPSS_MAX_TIME * 2)
            mNowValue = _CAPSS_MAX_TIME * 2;
        else
            mNowValue += _CapSS_CH2GetCaptureValue(); //读取捕获值
#endif
    }
#endif
#if (_CAPSS_CH_NUM > 3)
    else if (mNowCH == 3)
    {
        _CapSS_CH3OutHigh();   //充满电（高电平）
        _CapSS_CaptureReady(); //准备捕获计数
        _CapSS_CH3StartFEC();  //开始捕获计数
        _CapSS_CH3InHZ();      //开始放电
        while (_CapSS_CH3GetCaptureFlag())
        {
            if (_CapSS_CaptureIsOverflow())
                break;
        }                        //等待捕获低电平
        _CapSS_CH3StopCapture(); //停止捕获计数
#ifdef CAPSS_DEBUG
        if (_CapSS_CaptureIsOverflow())
            mVilTimes = _CAPSS_MAX_TIME;
        else
            mVilTimes = _CapSS_CH3GetCaptureValue(); //读取捕获值
#else
        if (_CapSS_CaptureIsOverflow() || mNowValue == _CAPSS_MAX_TIME * 2)
            mNowValue = _CAPSS_MAX_TIME * 2;
        else
            mNowValue += _CapSS_CH3GetCaptureValue(); //读取捕获值
#endif
    }
#endif
    _CapSS_EnableInt(); //开启中断
#ifdef CAPSS_DEBUG
    if(mVilTimes[mNowCH] == _CAPSS_MAX_TIME || mVihTimes[mNowCH] == _CAPSS_MAX_TIME)mNowValue[mNowCH] = _CAPSS_MAX_TIME * 2;
    else mNowValue[mNowCH] = (capss_value_t)mVilTimes[mNowCH] + mVihTimes[mNowCH];
#endif
#ifdef _CAPSS_USE_ASYNC_API 
    // 使用异步API时本函数没有返回值。
#else
    #ifdef CAPSS_DEBUG
    return mNowValue[mNowCH];
    #else
    return mNowValue;
    #endif
#endif
}
